package br.ufrj.neg.evento.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;

import br.ufrj.neg.bean.Idioma;
import br.ufrj.neg.constants.General;
import br.ufrj.neg.contatos.bean.ContatoBean;
import br.ufrj.neg.evento.bean.EventoBean;
import br.ufrj.neg.evento.bean.EventoContext;
import br.ufrj.neg.evento.bean.TipoArtefatoBean;
import br.ufrj.neg.evento.model.EventoModel;
import br.ufrj.neg.evento.model.TipoArtefatoModel;
import br.ufrj.neg.servlet.PageContext;
import br.ufrj.neg.usuario.bean.UsuarioBean;
import br.ufrj.neg.util.Data;


public class EventoServlet extends VelocityViewServlet {

		public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {			
			doPost(request,response);		
		}
		
		public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			HttpSession session = request.getSession();
			String action = request.getParameter("action");
			
			if( action== null ){
				if( session.getAttribute("idNegociacao") == null ){
					/*Acessando listagem de Eventos a partir do link Eventos na listagem de Negociacoes*/
					if( request.getParameter("idNegociacao") == null ){
						/*Acessando listagem de Eventos que não pelo link Eventos na listagem de Negociacoes*/
						request.getRequestDispatcher("/templates/errorPages/404.vm").forward(request, response);	
					}
					session.setAttribute("idNegociacao", Integer.valueOf( request.getParameter("idNegociacao") ));	
				}		
				loadAll(request,response);
			}
			else{
				if( session.getAttribute("idNegociacao")==null ){
					request.getRequestDispatcher("/templates/errorPages/404.vm").forward(request, response);
				}
				
				if(action.equals("load")){
					load(request,response);
				}
				else if(action.equals("update")){		
					update(request,response);				
				}
				else if(action.equals("delete")){
					delete(request,response);
				}
				else if(action.equals("insert")){
					insert(request,response);
				}
				else if(action.equals("form")){
					form(request,response);
				}			
				
			}
			
		
						
		}
		
		private void delete(HttpServletRequest request,
				HttpServletResponse response) throws IOException, ServletException {
			
			//FIXME: _Verificar permissão para deletar?

			Integer idEvento = Integer.parseInt(request.getParameter("eventoId"));
			Idioma idioma = (Idioma) request.getAttribute("idioma");
			EventoBean eb = EventoModel.getEvento(idEvento, idioma);
			
			if( !checkPermission(eb, (UsuarioBean) request.getSession().getAttribute("usuarioBean") ) ){
				request.getRequestDispatcher("/templates/errorPages/404.vm").forward(request, response);
			}			
			
			try {
				EventoModel.removeEvento(idEvento);
			} catch (Exception e) {
				throw new ServletException();
			}
			
			loadAll(request,response);
		}
		
		private void loadAll(HttpServletRequest request,
				HttpServletResponse response) throws IOException{
			HttpSession session = request.getSession();
			Boolean async = Boolean.parseBoolean(request.getParameter("async"));
			
			setContentType(request, response);
			Context context = createContext(request, response);		
			
			Integer idNegociacao;	
			idNegociacao = (Integer) session.getAttribute("idNegociacao");
		
	 
			EventoContext eventoContext = new EventoContext(idNegociacao);
			context.put("eventoContext", eventoContext);
			
			//1
			Collection<EventoBean> eventos = EventoModel.getEventosPorNegociacao(eventoContext.getIdNegociacao());	
			context.put("eventos", eventos);
			
			
			//Problemas com a data
			JsonConfig jsonConfig = new JsonConfig();  
			jsonConfig.setExcludes( new String[]{ "dataInicio", "dataFim" } );  
			JSONArray jsonA = (JSONArray) JSONSerializer.toJSON( eventos, jsonConfig );   
			
			/*Removendo objeto Array com os participantes e deixando so a string*/
			for(int i=0;i<jsonA.size();i++){
				JSONObject js = (JSONObject) jsonA.get(i);
				js.remove("participantes");
			}
			String json = jsonA.toString().replace("\"", "\'");
			
			context.put("eventosJSON", json);
			context.put("pageContext",new PageContext(request));
			
			if(async){
				PrintWriter out = response.getWriter();
				
				out.println(json);
			}else{
				
				
				Template template = getTemplate("templates/evento/listaEvento.vm");
				mergeTemplate(template, context, response);
			}
		}
		
		private void load(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{		
			Integer idEvento = Integer.parseInt(request.getParameter("evento"));
			Idioma idioma = (Idioma) request.getAttribute("idioma");
			EventoBean evento = EventoModel.getEvento(idEvento,idioma);

			if( !checkPermission(evento, (UsuarioBean) request.getSession().getAttribute("usuarioBean") ) ){
				request.getRequestDispatcher("/templates/errorPages/404.vm").forward(request, response);
			}
			
			setContentType(request, response);
			Context context = createContext(request, response);		
			Boolean async = Boolean.parseBoolean(request.getParameter("async"));
		
			
			context.put("evento", evento);
			
			JsonConfig jsonConfig = new JsonConfig();  
			jsonConfig.setExcludes( new String[]{ "dataInicio", "dataFim" } );  
			JSONObject json = (JSONObject) JSONSerializer.toJSON( evento, jsonConfig );   
			context.put("eventoJSON", json);
			
			if(async){
				PrintWriter out = response.getWriter();
				
				out.println(json);
			}else{
				
				//FIXME Adicionar template
				Template template = getTemplate(".vm");
				mergeTemplate(template, context, response);
			}
			
			
		}
		
		private void insert(HttpServletRequest request,
				HttpServletResponse response) throws IOException, ServletException {
			
			PrintWriter out = response.getWriter();
			
			
			EventoBean evento = montaBean(request,response);
			Integer idEvento = EventoModel.insereEvento(evento);	
			
			out.print(idEvento);
			
		}

		/*
		 * Chama as rotinas inerentes ao processo de salvamento no BD
		 */
		private void update(HttpServletRequest request,
				HttpServletResponse response) throws ServletException, IOException {
					
			
			EventoBean evento = montaBean(request,response);
			if( !checkPermission(evento, (UsuarioBean) request.getSession().getAttribute("usuarioBean") ) ){
				request.getRequestDispatcher("/templates/errorPages/404.vm").forward(request, response);
			}
			
			try {
				EventoModel.atualizaEvento(evento);
				
				PrintWriter out = response.getWriter();
				out.print(evento.getId());
			} catch (Exception e) {
				throw new ServletException();
			}	
					
			
		}	
		
		private boolean checkPermission(EventoBean evento, UsuarioBean usuario){
			
			if(!EventoModel.checkNegociacao(evento.getIdNegociacao(),usuario.getId())){
				return false;
			}
			
			return true;
		}

		private EventoBean montaBean(HttpServletRequest request,HttpServletResponse response) throws ServletException {
			String json = (String) request.getParameter("json");
			JSONObject jsonObject = JSONObject.fromObject(json);
			
			//Mapa de class necessário para conversão do Bean correta
			Map classMap = new HashMap();  
			classMap.put( "participantes", ContatoBean.class); //Usa um ContatoBean  
			EventoBean evento = (EventoBean) JSONObject.toBean(jsonObject, EventoBean.class,classMap);
			
			try {
				//Montar Objeto Data 
				evento.setDataInicio(new Data(evento.getDtInicio(), evento.getHoraInicio()));
				evento.setDataFim(new Data(evento.getDtFim(), evento.getHoraFim()));
				
				//Retirar \n do memoria.
				evento.setMemoria(StringEscapeUtils.unescapeHtml(evento.getMemoria().replace("\n","").replace("\r","")));
			
			} catch (Exception e) {

				throw new ServletException(e);
			}
			
			return evento;
		}

		private void form(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
			
			HttpSession session = request.getSession();
			Context context = createContext(request, response);	
			setContentType(request, response);
			EventoBean evento;
			TipoArtefatoModel tam = new TipoArtefatoModel();
			
			Idioma idioma = (Idioma) request.getAttribute("idioma");
			context.put("pageContext",new PageContext(request));
			EventoContext eventoContext = new EventoContext((Integer) session.getAttribute("idNegociacao"));
			context.put("eventoContext", eventoContext);
			TipoArtefatoBean tab = new TipoArtefatoBean(idioma);
			context.put("tipoArtefatoDataSet", tam.listaTipoArtefato(tab));
			
			context.put("modelosMemoriaDataSet", EventoModel.getModelos());
			
			if( request.getParameterMap().containsKey("eventoId")){
				Integer idEvento = Integer.parseInt(request.getParameter("eventoId"));
				evento = EventoModel.getEvento(idEvento,idioma);
				
				if( !checkPermission(evento, (UsuarioBean) request.getSession().getAttribute("usuarioBean") ) ){
					request.getRequestDispatcher("/templates/errorPages/404.vm").forward(request, response);
				}							
				
				context.put("evento",evento);
			}
			else{
				
				evento = new EventoBean();
				evento.setDataInicio(new Data());
				evento.setDtInicio(evento.getDataInicio().getDataAAAAMMDD());
				evento.setDtFim(evento.getDataInicio().getDataAAAAMMDD());
				evento.setHoraInicio(evento.getDataInicio().getHora());
				evento.setHoraFim(evento.getDataInicio().getHora());
				context.put("evento",evento);
			}
	

			Template template = getTemplate("templates/evento/cadastroEvento.vm");
			mergeTemplate(template, context, response);

		}		
	
}
